Skip to content

Cap inherit_from recursion in DeploySpec::FileSystem - #1498

Open
aqeelvn wants to merge 1 commit into
checkout-less-deploy-specfrom
cap-inherit-from-recursion
Open

Cap inherit_from recursion in DeploySpec::FileSystem#1498
aqeelvn wants to merge 1 commit into
checkout-less-deploy-specfrom
cap-inherit-from-recursion

Conversation

@aqeelvn

@aqeelvn aqeelvn commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Stacked on #1497. Extracted from its review (thanks @timothysmith0609 for the catch).

What

build_config recurses through inherit_from chains with no bound. A cycle (a.ymlb.yml) recurses until SystemStackError — which is not a StandardError, so it escapes every rescue in the calling jobs — or, post-#1494, hard-blocks a worker thread until the 15-minute execution cap kills it. Cap the chain at 10 levels and raise a clear DeploySpec::Error naming the resolution path, so the broken configuration surfaces to the stack owner instead.

Why it matters beyond the obvious

  • Fixes today's production behavior (the :disabled path everyone runs).
  • Removes the one case in Evaluate cacheable deploy specs from the git object database #1497 where falling back was worse than not: GitObjectFileSystem's own inherit-depth guard fell back to this previously-uncapped path, converting a clean FallbackRequired into a stack overflow.

10 levels is generous — observed real chains are 2–3 deep. GitObjectFileSystem#build_config signature updated to match (extra depth param passed through super).

Tests

  • Cycle → DeploySpec::Error with a clear message (previously: infinite recursion)
  • 3-deep legitimate chain resolves normally with correct merge semantics

An inherit_from cycle (a.yml <-> b.yml) recursed until SystemStackError
-- which is not a StandardError, so it escaped every rescue in the
callers -- or, with the CacheDeploySpecJob execution cap, burned a
worker thread for 15 minutes. Raise a clear DeploySpec::Error at 10
levels instead, surfacing the broken configuration to the stack owner.

This also removes the one case where GitObjectFileSystem's fallback
was worse than not falling back: its own inherit-depth guard fell back
to this previously-uncapped code path.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant